﻿using System;
using System.Windows;
using System.Windows.Controls;
using GraphDrawer.GraphProvider;
using System.Windows.Browser;
using System.Windows.Shapes;
using System.Windows.Media;
using prefuse.action.layout.graph;
using System.Windows.Input;
using System.Collections.Generic;
using System.Linq;
using GraphLayout.Interface;


using System.Net;
using System.Windows.Documents;
using System.Windows.Media.Animation;
using prefuse.action.layout;
using System.Threading;

namespace GraphDrawer.SocialNetworks
{
    public partial class SocialNetworksList : IWizardController, ILayoutControler
    {
        private Root root;
        //DataProvider.DataProviderServiceSoapClient dl;

        public static readonly GraphProviderServiceSoapClient graphProvider = new GraphProviderServiceSoapClient();
        private static RoutedEventHandler popUpOk;
        private static RoutedEventHandler popUpClosed;
        public Type sourceMethod;
        public event RoutedEventHandler isSelectedSource;

        ImportNetwork import;
        GenerateNetwork generator;

        public String graphML;

        Graph g;

        private Dictionary<String, Type> typeMap;
        GraphProvider.GraphProviderServiceSoapClient cl = new GraphProviderServiceSoapClient();
        private Layout m_currentlayout;
        private bool layoutChanged = false;

        double oldMouseX = 0.0;
        double oldMouseY = 0.0;
        bool mouseLeftButtonPressed = false;

        private bool noZoomValueChanged = false;

        private Boolean isContinous = false;

        public Layout currentlayout
        {
            get
            {
                return m_currentlayout;
            }
            set
            {
                m_currentlayout = value;
                m_currentlayout.Controller = this;
                String name = (from v in typeMap
                               where v.Value == m_currentlayout.GetType()
                               select v.Key).First();
                layoutChooser.SelectedItem = name;
            }
        }
        public static Dictionary<GraphElement, GraphLayout.Interface.VisualItem> map = new Dictionary<GraphElement, GraphLayout.Interface.VisualItem>();
        

        #region IWizardController Members

        public EmptyPopUp PopUp { get; set; }

        #endregion

        #region ILayoutControler Members

        public void SuspendLayout()
        {
            foreach (var item in ControlPanel.Children)
            {
                if (item is Button)
                {
                    Button b = item as Button;
                    b.IsEnabled = false;
                }
                else
                    if (item is Slider)
                    {
                        Slider s = item as Slider;
                        s.IsEnabled = false;
                    }
            }

            //m_menu.LeftPanel.Visibility = Visibility.Collapsed;
        }

        public void ResumeLayout()
        {
            foreach (var item in ControlPanel.Children)
            {
                if (item is Button)
                {
                    Button b = item as Button;
                    b.IsEnabled = true;
                }
                else
                    if (item is Slider)
                    {
                        Slider s = item as Slider;
                        s.IsEnabled = true;
                    }
            }
            //m_menu.LeftPanel.Visibility = Visibility.Visible;
        }

        #endregion

        public SocialNetworksList(Root root)
        {
            InitializeComponent();
            this.root = root;

            PopUp = new EmptyPopUp();

            graphML = String.Empty;

            //*
            PopUp.Visibility = Visibility.Collapsed;
            LayoutRoot.Children.Add(PopUp); 

            //dl = new GraphDrawer.DataProvider.DataProviderServiceSoapClient();
            //dl.GetAvailableNetsCompleted += new EventHandler<GraphDrawer.DataProvider.GetAvailableNetsCompletedEventArgs>(dl_GetAvailableNetsCompleted);
            //loadSocialNetworksFromDB();
        }

        //void dl_GetAvailableNetsCompleted(object sender, GraphDrawer.DataProvider.GetAvailableNetsCompletedEventArgs e)
        //{
        //    var networks = e.Result;
        //    foreach (string net in networks)
        //    {
        //        socialNetworks.Items.Add(net);
        //    }
        //}

        //private void loadSocialNetworksFromDB()
        //{
        //    dl.GetAvailableNetsAsync();
        //}

        //private void loadSocialNetworkButton_Click(object sender, RoutedEventArgs e)
        //{
        //    SocialNetworkViewer viewer = new SocialNetworkViewer(socialNetworks.SelectedItem.ToString());
        //    root.LoadSocialNetworksViewer(viewer);
        //}

        private void importSocialNetworkButton_Click(object sender, RoutedEventArgs e)
        {
            import = new ImportNetwork(this);

            sourceMethod = import.GetType();
            popUpOk = new RoutedEventHandler(PopUp_Import);
            PopUp.btnOk.Content = "OK"; 
            PopUp.OK += popUpOk;
            PopUp.AddUserControl(import);
            PopUp.Visibility = Visibility.Visible;

        }

        private void createNetworkButton_Click(object sender, RoutedEventArgs e)
        {
            App.Current.Host.Content.IsFullScreen = false;

            generator = new GenerateNetwork(graphProvider, this);
            sourceMethod = generator.GetType();

            popUpOk = new RoutedEventHandler(PopUp_Save);
            popUpClosed = new RoutedEventHandler(PopUp_Closed);
            PopUp.btnOk.Content = "Save to file";
            PopUp.OK += popUpOk;
            PopUp.Closed += popUpClosed;
            PopUp.AddUserControl(generator);
            PopUp.Visibility = Visibility.Visible;
        }


        void PopUp_Import(object sender, RoutedEventArgs e) 
        {
            PopUp.OK -= popUpOk;
            graphML = import.graphML;

            graphProvider.CreateGraphFromGraphMLCompleted += new EventHandler<GraphProvider.CreateGraphFromGraphMLCompletedEventArgs>(graphProvider_GetGraph);
            graphProvider.CreateGraphFromGraphMLAsync(graphML);
            
        }

        void graphProvider_GetGraph(object sender, GraphProvider.CreateGraphFromGraphMLCompletedEventArgs e)
        {
            g = e.Result;
			Graph m_graph = e.Result;

            rootCanvas.Children.Clear();

            typeMap = Layout.ChildTypesNames(typeof(Layout));
            foreach (var item in typeMap)
                layoutChooser.Items.Add(item.Key);

            SuspendLayout();

            GraphLayout.GraphRepresentation.Graph gg = new GraphLayout.GraphRepresentation.Graph();
            gg.Nodes = new System.Collections.ObjectModel.ObservableCollection<VisualItem>();
            gg.Edges = new System.Collections.ObjectModel.ObservableCollection<GraphLayout.GraphRepresentation.EdgeItem>();
 
            currentlayout = new RadialTreeLayout("", gg, 100);
            currentlayout.setLayoutAnchor(new Point(rootCanvas.ActualWidth / 2.0, rootCanvas.ActualHeight / 2.0));
            currentlayout.Width = this.ActualWidth;
            currentlayout.Height = this.ActualHeight;
  
            //TODO: check for fiering events twice.
            this.MouseLeftButtonDown += new MouseButtonEventHandler(rootCanvas_MouseLeftButtonDown);
            this.MouseLeftButtonUp += new MouseButtonEventHandler(rootCanvas_MouseLeftButtonUp);
            this.MouseLeave += new MouseEventHandler(rootCanvas_MouseLeave);
            this.MouseMove += new MouseEventHandler(rootCanvas_MouseMove);

            map.Clear();

            foreach (var item in g.Vertices)
            {
                GraphElement elem = item;
                var node = CreateNodeCanvas(elem, this);
                node.NodeSelected += new MouseEventHandler(nodeCanvas_NodeSelected);
                gg.Nodes.Add(node);
                ((GraphLayout.GraphRepresentation.NodeItem)gg.Nodes.Last()).Graph = gg;
                ((GraphLayout.GraphRepresentation.NodeItem)gg.Nodes.Last()).X = (float)currentlayout.getLayoutAnchor().X;
                ((GraphLayout.GraphRepresentation.NodeItem)gg.Nodes.Last()).Y = (float)currentlayout.getLayoutAnchor().Y;
                gg.Nodes.Last().Element = item;
                map.Add(item, gg.Nodes.Last());

                ((GraphLayout.GraphRepresentation.NodeItem)gg.Nodes.Last()).MouseEnter += new MouseEventHandler(SetInfoPanel);
                ((GraphLayout.GraphRepresentation.NodeItem)gg.Nodes.Last()).MouseLeave += new MouseEventHandler(ResetInfoPanel);

                currentlayout.Children.Add((GraphLayout.GraphRepresentation.NodeItem)gg.Nodes.Last());
            }

            //DebugGraph(gg);//test
            foreach (var item in g.Edges)
            {
                var n1 = (from v in g.Vertices
                          where v.Id == item.Source
                          select v).First();
                var n2 = (from v in g.Vertices
                          where v.Id == item.Target
                          select v).First();

                GraphLayout.GraphRepresentation.EdgeItem e1 = new GraphLayout.GraphRepresentation.EdgeItem();
                e1.Target = map[n2];
                e1.Source = map[n1];
                e1.Graph = gg;

                gg.Edges.Add(e1);
            }

            try
            {
                currentlayout.Init();
                currentlayout.DrawLayout(100);
            }
            catch (Exception ex)
            {
                rootCanvas.Children.Add(new TextBlock()
                {
                    Text = ex.Message
                });
            };
            currentlayout.SetValue(Grid.ColumnProperty, 1);
            currentlayout.SetValue(Canvas.ZIndexProperty, -10);
            this.rootCanvas.Children.Add(currentlayout);

            ControlPanel.Visibility = Visibility.Visible;
        }

        public static GraphLayout.GraphRepresentation.NodeItem CreateNodeCanvas(GraphElement n, SocialNetworksList simulationPage)
        {
            Color projColor = Color.FromArgb(128, 100, 55, 55);

            Brush textColor = new SolidColorBrush(Colors.Black);
            Brush borderColor = new SolidColorBrush(Color.FromArgb(255, 50, 50, 50));

            Brush projBrush = new SolidColorBrush(Colors.LightGray);

            /*TextBlock title = new TextBlock() {
                Foreground = textColor,
                Text = text,
                FontSize = 12
            };*/

            double Height = 25d;
            double Width = 25d;
            //double Width = (title.ActualWidth + 4) < Height ? Height : title.ActualWidth + 4;

            GraphLayout.GraphRepresentation.NodeItem nodeCanvas = new GraphLayout.GraphRepresentation.NodeItem()
            {
                Width = Width,
                Height = Height
            };

            //nodeCanvas.Title = title;

            Ellipse nodeBkg = new Ellipse()
            {
                //Width = Width,
                //Height = Height,
                Width = 25d,
                Height = 25d,
                Fill = projBrush,
                Stroke = borderColor
            };


            //nodeBkg.RadiusX = 10;
            //nodeBkg.RadiusY = 10;

            nodeCanvas.Children.Add(nodeBkg);

            //nodeCanvas.Children.Add(title);

            #region Center the title

            //double left = (nodeBkg.Width - title.ActualWidth) / 2;
            //double top = (nodeBkg.Height - title.ActualHeight) / 2;
            //title.SetValue(Canvas.LeftProperty, left);
            //title.SetValue(Canvas.TopProperty, top);

            #endregion

            return nodeCanvas;
        }


        private void rootCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            (sender as SocialNetworksList).CaptureMouse();
            mouseLeftButtonPressed = true;
            oldMouseX = e.GetPosition(null).X;
            oldMouseY = e.GetPosition(null).Y;
            (sender as SocialNetworksList).Cursor = Cursors.Hand;
        }

        private void rootCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            (sender as SocialNetworksList).ReleaseMouseCapture();
            mouseLeftButtonPressed = false;
            (sender as SocialNetworksList).Cursor = Cursors.Arrow;
        }

        private void rootCanvas_MouseLeave(object sender, MouseEventArgs e)
        {
            mouseLeftButtonPressed = false;
        }

        private void rootCanvas_MouseMove(object sender, MouseEventArgs e)
        {
            if (mouseLeftButtonPressed == true && currentlayout.IsMouseCaptured == false)
                foreach (var node in currentlayout.Graph.Nodes)
                {
                    node.X += (float)(e.GetPosition(null).X - oldMouseX);
                    node.Y += (float)(e.GetPosition(null).Y - oldMouseY);
                }
            oldMouseX = e.GetPosition(null).X;
            oldMouseY = e.GetPosition(null).Y;
        }

        void nodeCanvas_NodeSelected(object sender, MouseEventArgs e)
        {
            var curr = sender as GraphLayout.GraphRepresentation.NodeItem;
            var prev = curr.Graph.PreviousSelectedNode as GraphLayout.GraphRepresentation.NodeItem;

            if (prev != null)
            {
                GraphElement n = prev.Element as GraphElement;

                String text = String.Empty;
                foreach (var description in n.Keys)
                {
                    if (description.Key == "stateName")
                    {
                        text = description.Value;
                        break;
                    }
                }

                ((Ellipse)prev.Children[0]).Fill = new SolidColorBrush(Colors.LightGray);
                ((Ellipse)prev.Children[0]).Stroke = new SolidColorBrush(Color.FromArgb(255, 50, 50, 50));
                ((Ellipse)prev.Children[0]).StrokeThickness = 1.0;
            }
            if (curr != null)
            {
                GraphElement n = curr.Element as GraphElement;

                //details.UpdateDetails(n.Keys);
                String text = String.Empty;

                foreach (var description in n.Keys)
                {
                    if (description.Key == "stateName")
                    {
                        text = description.Value;
                    }
                }


                int i = 0;
                //for (; i < stateChooser.Items.Count; i++)
                //{
                //    if (stateChooser.Items[i].ToString() == text)
                //        break;
                //}
                //stateChooser.SelectedIndex = i;
                ((Ellipse)curr.Children[0]).Fill = new SolidColorBrush(Color.FromArgb(128, 55, 55, 100));
                ((Ellipse)curr.Children[0]).Stroke = new SolidColorBrush(Color.FromArgb(255, 0, 0, 0));
                ((Ellipse)curr.Children[0]).StrokeThickness = 2.0;
            }
        }

        public static void SetInfoPanel(object sender, MouseEventArgs e)
        {
            GraphLayout.GraphRepresentation.NodeItem node = sender as GraphLayout.GraphRepresentation.NodeItem;

            if (node.FindName(node.GetHashCode() + "Info") != null)
                return;

            Canvas info = new Canvas()
            {
                Name = node.GetHashCode() + "Info"
            };

            string keys = "";
            var graphNode = (from v in map
                             where v.Value == node
                             select v.Key).First();
            foreach (var key in graphNode.Keys)
                keys += "  " + key.Key + " = " + key.Value + "  \n";
            keys = keys.Substring(0, keys.Length - 1);
            TextBlock t = new TextBlock()
            {
                Text = keys,
                FontSize = 12.0
            };

            Canvas border = new Canvas();

            Rectangle p = new Rectangle();
            p.Width = t.ActualWidth;
            p.Height = t.ActualHeight;
            p.Opacity = 0.8;
            p.Fill = new SolidColorBrush(Colors.White);
            p.Stroke = new SolidColorBrush(Colors.Blue);
            p.SetValue(Canvas.TopProperty, 0.0);
            p.SetValue(Canvas.LeftProperty, 0.0);
            p.RadiusX = 10;
            p.RadiusY = 10;

            Polygon tri = new Polygon();
            tri.Points = new PointCollection
            {
                new Point(node.Bounds.X + 50 + 33, node.Bounds.Y + (p.Height)),
                new Point(node.Bounds.X + 80 + 33, node.Bounds.Y + (p.Height)),
                new Point(node.Bounds.X + 33, node.Bounds.Y + (p.Height + 10 + 5))
            };
            tri.Fill = new SolidColorBrush(Colors.Blue);
            tri.Stroke = new SolidColorBrush(Colors.Blue);
            border.Children.Add(p);
            info.Children.Add(tri);

            Canvas.SetLeft(info, node.Bounds.X + node.Width - 30);
            Canvas.SetTop(info, node.Bounds.Y - (p.Height + 10));

            info.Children.Add(border);
            info.Children.Add(t);

            Canvas.SetZIndex(node, (int)node.GetValue(Canvas.ZIndexProperty) + 1);
            node.Children.Add(info);
        }

        public static void ResetInfoPanel(object sender, MouseEventArgs e)
        {
            GraphLayout.GraphRepresentation.NodeItem node = sender as GraphLayout.GraphRepresentation.NodeItem;

            Canvas c = null;
            foreach (var child in node.Children)
                if (child is Canvas)
                    if (((Canvas)child).Name == (node.GetHashCode() + "Info"))
                    {
                        c = (Canvas)child;
                        break;
                    }

            Canvas.SetZIndex(node, (int)node.GetValue(Canvas.ZIndexProperty) - 1);
            node.Children.Remove(c);
        }

        private void LayoutChooser_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            layoutChanged = true;
        }

        private void BalanceGraph_Click(object sender, RoutedEventArgs e)
        {
            Point anchor = currentlayout.getLayoutAnchor();

            noZoomValueChanged = true;
            zoom.Value = 4;

            if (layoutChanged == true)
            {
                layoutChanged = false;

                GraphLayout.GraphRepresentation.Graph g = (GraphLayout.GraphRepresentation.Graph)currentlayout.Graph;
                GraphLayout.GraphRepresentation.Graph graph = new GraphLayout.GraphRepresentation.Graph();
                graph.Nodes = new System.Collections.ObjectModel.ObservableCollection<VisualItem>();
                graph.Edges = new System.Collections.ObjectModel.ObservableCollection<GraphLayout.GraphRepresentation.EdgeItem>();

                GraphLayout.GraphRepresentation.NodeItem root = null;
                if (currentlayout is TreeLayout)
                    root = currentlayout.getLayoutRoot();

                var type = typeMap[layoutChooser.SelectedItem.ToString()];
                //currentlayout.Children.Clear();
                rootCanvas.Children.Remove(currentlayout);
                currentlayout = (Layout)Activator.CreateInstance(type, new object[] { graph });

                Dictionary<VisualItem, VisualItem> mapGGraph = new Dictionary<VisualItem, VisualItem>();
                foreach (var item in g.Nodes)
                {
                    GraphLayout.GraphRepresentation.NodeItem node = (GraphLayout.GraphRepresentation.NodeItem)item;
                    UIElement nodeBkg = node.Children[0];
                    //UIElement title = node.Children[1];
                    node.Children.Clear();
                    GraphLayout.GraphRepresentation.NodeItem nodeCanvas = new GraphLayout.GraphRepresentation.NodeItem()
                    {
                        Width = node.Width,
                        Height = node.Height,
                        //Title = node.Title
                    };
                    nodeCanvas.NodeSelected += new MouseEventHandler(nodeCanvas_NodeSelected);
                    nodeCanvas.Children.Add(nodeBkg);
                    //nodeCanvas.Children.Add(title);
                    graph.Nodes.Add(nodeCanvas);
                    ((GraphLayout.GraphRepresentation.NodeItem)graph.Nodes.Last()).Graph = graph;
                    ((GraphLayout.GraphRepresentation.NodeItem)graph.Nodes.Last()).X = node.X;
                    ((GraphLayout.GraphRepresentation.NodeItem)graph.Nodes.Last()).Y = node.Y;
                    graph.Nodes.Last().Element = node.Element;
                    mapGGraph.Add(node, graph.Nodes.Last());

                    ((GraphLayout.GraphRepresentation.NodeItem)graph.Nodes.Last()).MouseEnter += new MouseEventHandler(SetInfoPanel);
                    ((GraphLayout.GraphRepresentation.NodeItem)graph.Nodes.Last()).MouseLeave += new MouseEventHandler(ResetInfoPanel);

                    currentlayout.Children.Add((GraphLayout.GraphRepresentation.NodeItem)graph.Nodes.Last());
                }
                foreach (var edge in g.Edges)
                {
                    var n1 = (from n in g.Nodes
                              where n == edge.Source
                              select n).First();
                    var n2 = (from n in g.Nodes
                              where n == edge.Target
                              select n).First();

                    GraphLayout.GraphRepresentation.EdgeItem e1 = new GraphLayout.GraphRepresentation.EdgeItem();
                    e1.Source = mapGGraph[n1];
                    e1.Target = mapGGraph[n2];
                    e1.Graph = graph;

                    graph.Edges.Add(e1);
                }

                Dictionary<GraphElement, VisualItem> newMap = new Dictionary<GraphElement, VisualItem>();
                GraphLayout.Interface.VisualItem vi = null;
                foreach (var item in map)
                    if (mapGGraph.TryGetValue(item.Value, out vi) == true)
                        newMap.Add(item.Key, mapGGraph[item.Value]);
                    map = newMap;

                if (root != null && currentlayout is TreeLayout)
                    ((TreeLayout)currentlayout).setLayoutRoot((GraphLayout.GraphRepresentation.NodeItem)mapGGraph[root]);

                if (g.PreviousSelectedNode != null)
                    graph.PreviousSelectedNode = mapGGraph[g.PreviousSelectedNode];
                if (g.SelectedNode != null)
                {
                    graph.SelectedNode = mapGGraph[g.SelectedNode];
                    SelectNode((GraphLayout.GraphRepresentation.NodeItem)mapGGraph[g.SelectedNode]);
                }

                //currentlayout.Width = m_menu.ContentHost.Width;
                //currentlayout.Height = m_menu.ContentHost.Height;
                currentlayout.Width = this.Width;
                currentlayout.Height = this.Height;
                currentlayout.SetValue(Canvas.TopProperty, 1.0);
                currentlayout.SetValue(Canvas.LeftProperty, 1.0);
                rootCanvas.Children.Insert(0, currentlayout);
            }

            currentlayout.setLayoutAnchor(anchor);

            currentlayout.Init();
            currentlayout.DrawLayout(100);
        }

        private void SelectNode(GraphLayout.GraphRepresentation.NodeItem node)
        {
            node.Select();
        }

        private void Zoom_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (currentlayout == null || noZoomValueChanged == true)
            {
                noZoomValueChanged = false;
                return;
            }

            double centralX = rootCanvas.ActualWidth / 2;
            double centralY = rootCanvas.ActualHeight / 2;
            //double centralX = currentlayout.Width / 2;
            //double centralY = currentlayout.Height / 2;
            double scale = (e.NewValue + 1) / (e.OldValue + 1);
            foreach (var node in currentlayout.Graph.Nodes)
            {
                double relX = node.X - centralX;
                double relY = node.Y - centralY;

                node.X = (float)(scale * relX + centralX);
                node.Y = (float)(scale * relY + centralY);
            }
        }



        void PopUp_Save(object sender, RoutedEventArgs e)
        {
            //nacisniecie "Save to file"
            PopUp.OK -= popUpOk;
            //isSelectedSource.Invoke(sender, e);

            string myTextFile = CreateGraphFCN(generator.graph);

            HtmlDocument doc = HtmlPage.Document;
            HtmlElement downloadData = doc.GetElementById("DownloadData");
            downloadData.SetAttribute("value", myTextFile);

            HtmlElement fileName = doc.GetElementById("FileName");
            fileName.SetAttribute("value", "myNet" + generator.graph.Vertices.Count + ".graphml.xml");
            doc.Submit("generateFileForm");
        }

        void PopUp_Closed(object sender, RoutedEventArgs e)
        {
            PopUp.OK -= popUpOk;
        }

        private void exit_Click(object sender, RoutedEventArgs e)
        {  		
			root.LoadMainMenu();
        }

        private string CreateGraphFCN(Graph g)
        {
            int condition = Convert.ToInt32(generator.condition.Text);

            String siec = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + Environment.NewLine +
            "<graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns " +
            "http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd\">" + Environment.NewLine +
            "  <key id=\"id\" for=\"node\" attr.name=\"id\" attr.type=\"string\" />" + Environment.NewLine +
            "  <key id=\"name\" for=\"node\" attr.name=\"name\" attr.type=\"string\" />" + Environment.NewLine +
            "  <key id=\"surname\" for=\"node\" attr.name=\"surname\" attr.type=\"string\" />" + Environment.NewLine +
            "  <key id=\"birthdate\" for=\"node\" attr.name=\"birthdate\" attr.type=\"string\" />" + Environment.NewLine +
            "  <key id=\"photo\" for=\"node\" attr.name=\"photo\" attr.type=\"string\" />" + Environment.NewLine +
            "  <key id=\"location\" for=\"node\" attr.name=\"location\" attr.type=\"string\" />" + Environment.NewLine +
            "  <key id=\"locationX\" for=\"node\" attr.name=\"locationX\" attr.type=\"string\" />" + Environment.NewLine +
            "  <key id=\"locationY\" for=\"node\" attr.name=\"locationY\" attr.type=\"string\" />" + Environment.NewLine +
            "  <key id=\"street\" for=\"node\" attr.name=\"street\" attr.type=\"string\" />" + Environment.NewLine +
            "  <key id=\"town\" for=\"node\" attr.name=\"town\" attr.type=\"string\" />" + Environment.NewLine +
            "  <key id=\"postalcode\" for=\"node\" attr.name=\"postalcode\" attr.type=\"string\" />" + Environment.NewLine +
            "  <key id=\"country\" for=\"node\" attr.name=\"country\" attr.type=\"string\" />" + Environment.NewLine +
            "  <key id=\"stateName\" for=\"node\" attr.name=\"stateName\" attr.type=\"string\" />" + Environment.NewLine +
            " <graph edgedefault=\"undirected\">" + Environment.NewLine;

            int j = 1;
            String xmlNode;
            foreach (var node in g.Vertices)
            {
                xmlNode = "<node id=\"" + Convert.ToString(node.Id) + "\">" + Environment.NewLine;

                xmlNode +=
        "      <data key=\"id\">" + Convert.ToString(node.Id) + "</data>" + Environment.NewLine +
        "      <data key=\"name\">name"+j+"</data>" + Environment.NewLine +
        "      <data key=\"surname\">surname" + j + "</data>" + Environment.NewLine +
        "      <data key=\"birthdate\">"+DateTime.Now+"</data>" + Environment.NewLine +
        "      <data key=\"photo\">http://nosoifighters.studentlive.pl/GetImage.aspx?id=44</data>" + Environment.NewLine +
        "      <data key=\"location\">location" + j + "</data>" + Environment.NewLine +
        "      <data key=\"locationX\">0</data>" + Environment.NewLine +
        "      <data key=\"locationY\">0</data>" + Environment.NewLine +
        "      <data key=\"street\">street" + j + "</data>" + Environment.NewLine +
        "      <data key=\"town\">town" + j + "</data>" + Environment.NewLine +
        "      <data key=\"postalcode\"></data>" + Environment.NewLine +
        "      <data key=\"country\">country" + j + "</data>" + Environment.NewLine +
        "      <data key=\"stateName\">Susceptible</data>" + Environment.NewLine + "</node>" + Environment.NewLine;
               
                
                //TODO: jesli zostanie skonczony edytor
                //String key = "<data key=\"";
                //HashSet<String>.Enumerator e = node.attributes.GetEnumerator();
                //while (e.MoveNext())
                //{
                //    String attName = e.ToString();
                //    String att = e.Current;
                //}
                siec += xmlNode;

                j++;
            }

            String xmlEdge;
            int i = 0;
            foreach (var edge in g.Edges)
            {
                xmlEdge = "<edge id=\"" + (i++) + "\" source=\"" + edge.Source + "\" target=\"" + edge.Target + "\" condition=\"" + condition + "\" " + "/>" + Environment.NewLine; 
                siec += xmlEdge;
            }

            siec += "  </graph>" + Environment.NewLine + "</graphml>";

            return siec;
        }
    }
}
